package jehc.cloud.route.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import jehc.cloud.common.base.BaseService;
import jehc.cloud.common.cache.redis.RedisUtil;
import jehc.cloud.common.constant.CacheConstant;
import jehc.cloud.common.util.ExceptionUtil;
import jehc.cloud.common.util.JsonUtil;
import jehc.cloud.route.dao.DynamicRouteDao;
import jehc.cloud.route.model.DynamicRoute;
import jehc.cloud.route.publisher.GatewayChannelUtil;
import jehc.cloud.route.publisher.GatewayNettyUtil;
import jehc.cloud.route.service.DynamicRouteService;
import jehc.cloud.route.vo.ChannelEntity;
import jehc.cloud.route.vo.RequestInfo;
import jehc.cloud.route.vo.RouteEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

/**
 * @Desc 路由信息
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Service
@Slf4j
public class DynamicRouteServiceImpl extends BaseService implements DynamicRouteService {

	@Autowired
	private DynamicRouteDao dynamicRouteDao;

	@Autowired
	private RedisUtil redisUtil;

	@Autowired
	GatewayChannelUtil gatewayChannelUtil;

	@Autowired
	GatewayNettyUtil gatewayNettyUtil;

	@Value("${jehc.cloud.route.clientId:GatewayRoteId}")
	private String clientId;//客户端id（每个服务对应一个客户端唯一id）

	@Value("${jehc.cloud.route.clientGroupId:GatewayGroupId}")
	private String clientGroupId;//组Id（可以存多个服务共享一个组Id）


	/**
	 * 查询列表
	 * @param condition
	 * @return
	 */
	public List<DynamicRoute> getDynamicRouteListByCondition(Map<String, Object> condition){
		return dynamicRouteDao.getDynamicRouteListByCondition(condition);
	}

	/**
	 * 查询对象
	 * @param id
	 * @return
	 */
	public DynamicRoute getDynamicRouteById(String id){
		return dynamicRouteDao.getDynamicRouteById(id);
	}

	/**
	 * 添加
	 * @param dynamicRoute
	 * @return
	 */
	public int addDynamicRoute(DynamicRoute dynamicRoute){
		dynamicRoute.setId(toUUID());
		dynamicRoute.setCreate_time(getDate());
		dynamicRoute.setCreate_id(getXtUid());
		int i = dynamicRouteDao.addDynamicRoute(dynamicRoute);
		sync();
		notifyGateway(dynamicRoute.getId(),"add");//通知网关更新路由
		return i;
	}

	/**
	 * 修改
	 * @param dynamicRoute
	 * @return
	 */
	public int updateDynamicRoute(DynamicRoute dynamicRoute){
		dynamicRoute.setUpdate_time(getDate());
		dynamicRoute.setUpdate_id(getXtUid());
		int i = dynamicRouteDao.updateDynamicRoute(dynamicRoute);
		sync();
		notifyGateway(dynamicRoute.getId(),"update");//通知网关更新路由
		return i;
	}

	/**
	 * 删除
	 * @param condition
	 * @return
	 */
	public int delDynamicRoute(Map<String, Object> condition){
		List<DynamicRoute> dynamicRouteList = dynamicRouteDao.getDynamicRouteListByCondition(condition);
		if(!CollectionUtil.isEmpty(dynamicRouteList)){
			for(DynamicRoute dynamicRoute : dynamicRouteList){
				boolean res = notifyGateway(dynamicRoute.getId(),"delete");//通知网关更新路由
				if(!res){
					log.warn("通知网关异常：{}",dynamicRoute);
					throw new ExceptionUtil("通知网关异常：{}");
				}
			}
		}
		int i = dynamicRouteDao.delDynamicRoute(condition);
		sync();
		return i;
	}

	/**
	 * 同步缓存
	 */
	private void sync(){
		log.info("开始同步路由...");
		Map<String,Object> condition = new HashMap<>();
		List<DynamicRoute> dynamicRouteList = dynamicRouteDao.getDynamicRouteList(condition);
		if(!CollectionUtil.isEmpty(dynamicRouteList)){
			for(DynamicRoute dynamicRoute: dynamicRouteList){
				redisUtil.hset(CacheConstant.JEHC_ROUTE, dynamicRoute.getId(),JsonUtil.toFastJson(dynamicRoute));
			}
		}
		log.info("同步路由完毕，共计{}条数据",dynamicRouteList.size());
	}

	/**
	 * 更新状态
	 * @param dynamicRoute
	 * @return
	 */
	public int updateStatus(DynamicRoute dynamicRoute){
		dynamicRoute.setUpdate_time(getDate());
		dynamicRoute.setUpdate_id(getXtUid());
		int i = dynamicRouteDao.updateStatus(dynamicRoute);
		sync();
		if(dynamicRoute.getStatus().equals(0)){
			notifyGateway(dynamicRoute.getId(),"add");//通知网关更新路由
		}
		if(dynamicRoute.getStatus().equals(1)){
			notifyGateway(dynamicRoute.getId(),"delete");//通知网关更新路由
		}
		return i;
	}

	/**
	 * 通知网关
	 * @param id
	 * @param method
	 * @return
	 */
	private Boolean notifyGateway(String id,String method){
		List<ChannelEntity> channelEntities = gatewayChannelUtil.get(clientGroupId);
		boolean res = true;
		if(CollectionUtil.isNotEmpty(channelEntities)){
			RouteEntity routeEntity = new RouteEntity(id,method);
			res = send(channelEntities,routeEntity);
		}
		return res;
	}

	/**
	 * 执行发送
	 * @param channelEntities
	 * @param routeEntity
	 */
	private Boolean send(List<ChannelEntity> channelEntities,RouteEntity routeEntity){
		boolean res = true;
		try {
			Random random = new Random();
			int size = random.nextInt(channelEntities.size());
			ChannelEntity channelEntity = channelEntities.get(size);
			RequestInfo requestInfo = new RequestInfo();
			requestInfo.setData(routeEntity);
			channelEntity.setRequestInfo(requestInfo);
			res = gatewayNettyUtil.sendMessage(channelEntity);
			if(res){
				log.info("通知网关路由成功，{}-{}",routeEntity,channelEntities);
			}
		}catch (Exception e){
			log.info("通知网关路由异常，{}-{}-{}",e,channelEntities,routeEntity);
			res = false;
		}
		return res;
	}
}
